package com.example.demo.io;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

public class NoBlockingIo {

    public static void main(String[] args) throws IOException {
        // channel通道打开
        ServerSocketChannel channel = ServerSocketChannel.open();
        channel.socket().bind(new InetSocketAddress(9000));
        channel.configureBlocking(false);// 设置非阻塞

        // 打开selector
        Selector selector = Selector.open();
        channel.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println("服务端启动成功");

        while (true) {
            selector.select();// 阻塞
            // selector是抽象接口  真正实现是EpollSelectorImpl
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                if (key.isAcceptable()) {// 连接事件  进行连接和注册
                    ServerSocketChannel server = (ServerSocketChannel) key.channel();
                    SocketChannel ch = server.accept();
                    ch.configureBlocking(false);// 非阻塞
                    ch.register(selector, SelectionKey.OP_READ);
                    System.out.println("客户端连接成功");
                } else if (key.isReadable()) {// 进行事件读取
                    System.out.println("服务端收到消息");


                    iterator.remove();// 删除本次事件处理器  防止下次重复处理
                } else if (key.isValid()) {
                    System.out.println("客户端断开连接");
                }
            }
        }
    }
}
